#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "gd32w51x.h"
#include "microList.h"
#include "microTask.h"
#include "microTimer.h"
#include "microTime.h"
#include "microDelay.h"


/* 延时头节点 */
MicroListType g_typeMicroListDelayHead = {&g_typeMicroListDelayHead, &g_typeMicroListDelayHead, MICRO_LIST_VALUE_MAX, NULL};


int8_t cMicroDelay(MicroTaskType *ptypeTaskHandle, int64_t lTime)
{
    MicroTimerTypeDef *ptypeTimer = NULL;
    MicroListType *ptypeList = NULL;
    int8_t cError = 0;

    if(ptypeTaskHandle == NULL)
        return -1;

    ptypeTimer = &(ptypeTaskHandle->timer);

    ptypeList = &(ptypeTaskHandle->list);

    /* 重新设置延时参数 */
    cError |= cMicroTimerSetUs(ptypeTimer, lTime, MicroTimerOpen);

    /* 到达定时时间点作为参数进行初始化 */
    cError |= cMicroListInit(ptypeList, ptypeTimer->timeStop);

    /* 按顺序插入到延时链表 */
    cError |= cMicroListInsert(&g_typeMicroListDelayHead, ptypeList);

    return cError;
}

int8_t cMicroDelayUntil(MicroTaskType *ptypeTaskHandle, int64_t lTime)
{
    MicroTimerTypeDef *ptypeTimer = NULL;
    MicroListType *ptypeList = NULL;
    int8_t cError = 0;

    if(ptypeTaskHandle == NULL)
        return -1;

    ptypeTimer = &(ptypeTaskHandle->timer);

    ptypeList = &(ptypeTaskHandle->list);

    /* 延时参数增加一个延时周期 */
    cError |= cMicroTimerReload(ptypeTimer);

    /* 到达定时时间点作为参数进行初始化 */
    cError |= cMicroListInit(ptypeList, ptypeTimer->timeStop);

    /* 按顺序插入到延时链表 */
    cError |= cMicroListInsert(&g_typeMicroListDelayHead, ptypeList);

    return cError;
}

int8_t cMicroDelayMachine(void)
{
    MicroListType *ptypeListNow = g_typeMicroListDelayHead.pNext;;
    MicroTaskType *ptypeTaskNow = ptypeListNow->pElement;
    int8_t cError = 0;

    /* 查询链表第1个元素是否到期 */
    while((ptypeListNow != &g_typeMicroListDelayHead) && (enumMicroTimerGetState(&(ptypeTaskNow->timer)) == MicroTimerOver))
    {
        cError |= cMicroTimerClose(&(ptypeTaskNow->timer));

        /* 移出延时链表 */
        cError |= cMicroListRemove(ptypeListNow);

        /* 把任务插入到就绪链表 */
        cError |= cMicroTaskResume(ptypeTaskNow);

        /* 再次指向链表第1个元素 */
        ptypeListNow = g_typeMicroListDelayHead.pNext;
        ptypeTaskNow = ptypeListNow->pElement;
    }

    return cError;
}
